#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = '海龟交易法则'
__author__ = 'HaiFeng'
__mtime__ = '2016/8/25'
"""

from py_at.Data import Data
from py_at.strategy import Strategy
from py_at.Enums import *
import talib
from py_at.Bar import Bar



#TODO 加仓bar不止损这个没实现饿
class HaiGui(Strategy):
	""""""
	def __init__(self,cfg):
		super().__init__(cfg)

		if cfg == "":
			self.Params['Lots'] = 1
			self.Params['RiskRatio'] = 1  # % Risk Per N ( 0 - 100)
			self.Params['ATRLength'] = 20  # 平均波动周期 ATR Length
			self.Params['boLength'] = 20  # 短周期 BreakOut Length
			self.Params['fsLength'] = 55  # 长周期 FailSafe Length
			self.Params['teLength'] = 10  # 离市周期 Trailing Exit Lengt

		self.CiShu = 0   #加仓次数
		self.timeD = ''  #是否是一根k线
		self.SendOrderThisBar =False #当前bar是否存在交易
		self.atrbeishu=1.5




	def OnBarUpdate(self,data=Data,bar=Bar):
		""""""
		if self.CurrentBar < self.Params['fsLength']:
			return


		atr = talib.ATR(self.H, self.L, self.C, self.Params['ATRLength'])

		lots = self.Params['Lots']

		DonchianHi = talib.MAX(self.H, self.Params['boLength'])[-2]   #短周期
		DonchianLo = talib.MIN(self.L, self.Params['boLength'])[-2]

		fsDonchianHi = talib.MAX(self.H, self.Params['fsLength'])[-2]  #长周期
		fsDonchianLo = talib.MIN(self.L, self.Params['fsLength'])[-2]

		ExitHighestPrice = talib.MAX(self.H, self.Params['teLength'])[-2]  #止损线
		ExitLowestPrice = talib.MIN(self.L, self.Params['teLength'])[-2]

		if len(atr) < 2:
			return

		N = atr[-2]


		# if self.Excange=='OKEX': #虚拟货币的需要单独算
		# 	self.TurtleUnits = (self.floatProfit * 1 / 100 / (N * self.PriceTick * self.VolumeMultiple))  # 计算交易手数
		# 	self.TurtleUnits = self.TurtleUnits * self.C[-1]
		# 	self.TurtleUnits = self.TurtleUnits if self.TurtleUnits > 1 else 1  # 手数进行过滤
		# 	self.TurtleUnits=int(self.TurtleUnits)
		# else:
		self.TurtleUnits = round((self.floatProfit * 1 / 100) / (N * self.PriceTick * self.VolumeMultiple),2)  # 计算交易手数
		#self.TurtleUnits = self.TurtleUnits if self.TurtleUnits > 1 else 1  # 手数进行过滤

		# self.TurtleUnits = int((self.floatProfit * 1 / 100) / (N * self.PriceTick * self.VolumeMultiple))  # 计算交易手数
		# self.TurtleUnits = self.TurtleUnits if self.TurtleUnits > 1 else 1  # 手数进行过滤


		if self.Position == 0:
			# if self.H[-1] > DonchianHi:
			# 	price = max(min(self.H[-1], DonchianHi), self.O[-1])
			# 	self.Buy(price, lots, '上轨')
			# elif self.L[-1] < DonchianLo:
			# 	price = min(max(self.L[-1], DonchianLo), self.O[-1])
			# 	self.SellShort(price, lots, '下轨')
			#长期突破
			if self.H[-1] > fsDonchianHi:
				price = max(min(self.H[-1], fsDonchianHi), self.O[-1])
				print("突破上轨 {0}-买{1}手 {2}".format(self.D[-1],self.TurtleUnits, price))

				self.SendOrderThisBar = True          #当前bar有过交易
				self.PreBreakoutFailure = False       #上次突破是否失败
				self.Buy(price, self.TurtleUnits, '上轨-fs')
				self.CiShu =1
			elif self.L[-1] < fsDonchianLo:
				price = min(max(self.L[-1], fsDonchianLo), self.O[-1])
				print("突破下轨 {0}-卖{1}手 {2}".format(self.D[-1],self.TurtleUnits,price))

				self.SendOrderThisBar = True  # 当前bar有过交易
				self.PreBreakoutFailure = False  # 上次突破是否失
				self.SellShort(price, self.TurtleUnits, '下轨-fs')
				self.CiShu = 1
		elif self.Position > 0:
			if self.L[-1] < ExitLowestPrice:               #突破止损线 进行止损
				price = min(self.O[-1], max(self.L[-1], ExitLowestPrice))
				print("{0}-平多止损{1} {2}".format(self.D[-1],self.PositionLong, price))
				self.Sell(price, self.PositionLong, 'exit-价格需优化') #止损
				self.CiShu = 0
			else:
				# if(self.O[-1] >= self.LastEntryPriceLong + 0.5 * N ):#如果开盘就超过设定的 ，那么直接开盘价增仓 下面的max已经包括了开盘价格
				# 	self.Buy(self.TurtleUnits,self.O[-1])
				# 	self.SendOrderThisBar = True        #上次突破成功了

				if self.H[-1] >= self.LastEntryPriceLong + self.atrbeishu * N and self.CiShu<3:    #如果最高价突破了  那么用最高价进行加仓
					price = max(self.O[-1], self.LastEntryPriceLong + self.atrbeishu * N)
					print("{0}-多加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits, price))
					self.Buy(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-多'))
					self.SendOrderThisBar = True          #上次突破成功了
					self.CiShu = self.CiShu + 1
				if self.H[-1] >= self.LastEntryPriceLong + self.atrbeishu * N and self.CiShu<3:    #如果最高价突破了  那么用最高价进行加仓
					price = max(self.O[-1], self.LastEntryPriceLong + self.atrbeishu * N)
					print("{0}-多加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits, price))
					self.Buy(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-多'))
					self.SendOrderThisBar = True          #上次突破成功了
					self.CiShu = self.CiShu + 1
				if self.H[-1] >= self.LastEntryPriceLong + self.atrbeishu * N and self.CiShu<3:    #如果最高价突破了  那么用最高价进行加仓
					price = max(self.O[-1], self.LastEntryPriceLong + self.atrbeishu * N)
					print("{0}-多加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits, price))
					self.Buy(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-多'))
					self.SendOrderThisBar = True          #上次突破成功了
					self.CiShu = self.CiShu + 1


				elif self.L[-1]<=self.LastEntryPriceLong - 2 * N and self.SendOrderThisBar==False:
					price = self.LastEntryPriceLong - 2 * N
					price = self.O[-1] if price>self.O[-1] else price
					print("{0}-atr止损多仓{1}手 价格{2}".format(self.D[-1], self.PositionLong, price))
					self.Sell(price,self.PositionLong)      #atr止损
					self.CiShu = 0




		elif self.Position < 0:
			if self.H[-1] > ExitHighestPrice:
				price = max(self.O[-1], min(self.H[-1], ExitHighestPrice))
				print("{0}-空仓通道止损{1}手 {2}".format(self.D[-1],self.PositionShort,price))
				self.BuyToCover(price, self.PositionShort, 'exit')  #止损
				self.CiShu = 0


			else:
				if self.L[-1] <= self.LastEntryPriceShort - self.atrbeishu * N and self.CiShu<3:
					price = min(self.O[-1], self.LastEntryPriceShort - self.atrbeishu * N)
					print("{0}-空加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits,price))
					self.SellShort(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-空'))
					self.SendOrderThisBar = True  # 上次突破成功了
					self.CiShu = self.CiShu + 1
				if self.L[-1] <= self.LastEntryPriceShort - self.atrbeishu * N and self.CiShu<3:
					price = min(self.O[-1], self.LastEntryPriceShort - self.atrbeishu * N)
					print("{0}-空加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits,price))
					self.SellShort(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-空'))
					self.SendOrderThisBar = True  # 上次突破成功了
					self.CiShu = self.CiShu + 1
				if self.L[-1] <= self.LastEntryPriceShort - self.atrbeishu * N and self.CiShu<3:
					price = min(self.O[-1], self.LastEntryPriceShort - self.atrbeishu * N)
					print("{0}-空加仓{1}手 价格{2}".format(self.D[-1],self.TurtleUnits,price))
					self.SellShort(price, self.TurtleUnits, '{0},{1}'.format(N, '加仓-空'))
					self.SendOrderThisBar = True  # 上次突破成功了
					self.CiShu = self.CiShu + 1
				if(self.D[-1]=='2018-08-23 21:00:00'):
					print("")

				elif self.H[-1]>=self.LastEntryPriceShort + 2 * N and self.SendOrderThisBar==False:
					price =self.LastEntryPriceShort + 2 * N
					price = self.O[-1] if price < self.O[-1] else price
					print("{0}-atr止损空仓{1}手 价格{2}".format(self.D[-1], self.PositionShort, price))
					self.BuyToCover(price,self.PositionShort)
					self.CiShu = 0

		# 可以放置一个bar一个变动的逻辑
		if (self.timeD != self.D[-1]):
			self.SendOrderThisBar = False  # 每次新bar来的时候重置为False
			self.timeD = self.D[-1]
	# def FixPrice(self, dire, price):
	# 	"""修正发单价格"""
	# 	if dire == Direction.Buy:
	# 		return max(self.O[-1], price)
	# 	else:
	# 		return min(self.O[-1], price)
